# !/usr/bin/python
# -*- coding: utf-8 -*-

# THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),  
# to deal in the Software without restriction, including without limitation  
# the rights to use, copy, modify, merge, publish, distribute, sublicense,  
# and/or sell copies of the Software, and to permit persons to whom the  
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in 
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
# DEALINGS IN THE SOFTWARE.

# artist.py
# written by: 
#     Jan Jokela <jan@devion.org>

import sys, os
from qgl import scene
import base.config.config as config
import base.config.data as config_data
from fluid.eye import *
import fluid.actions as actions
import fluid.visuals as visuals
import data
import base.background as background
import base.topbar as topbar

class MusicArtist(object):
    def __init__(self):
        self.artist = data.artist
        eventhandler.subscribe(self)
        self.albumart_bk_view = AlbumArtBackgroundView()
        #self.albumart_view = AlbumArtView(data.albums)
        self.topbar = topbar.TopBar(self)
        self.background = background.Background()
        self.tracklist = TrackList(self, self.artist)
        #self.album_info = AlbumInfo(self.album)
        
    def handle_events(self, events):
        if config.input == "keyboard + mouse":
            for event in events:
                if event.type is KEYUP:
                    if event.key == K_SPACE:
                        self.destroy()
                        import base.menu as menu
                        menu.MainMenu()
                        root_node.accept(compiler)   
                        
    def destroy(self):
        eventhandler.unsubscribe(self)
        self.topbar.destroy()
        self.background.destroy()
        self.tracklist.destroy()
        self.albumart_bk_view.destroy()
        #self.albumart_view.destroy()
        #self.album_info.destroy()
        
class TrackList(object):
    def __init__(self, parent, artist):
        self.parent = parent
        self.artist = artist
        eventhandler.subscribe(self)
        self.mouse_active = mousehandler.active()
        self.tracks = []
        for item in data.audio_library:
            if item.artist == self.artist:
                if not item.title in self.tracks: 
                    self.tracks.append(item)
        self.draw()
        self.pos = data.artist_pos
        self.scroll()
    
    def draw(self):
        self.color = qgl.scene.state.Color((1.0,1.0,1.0,0.0))
        if self.mouse_active:
            self.color_mouse = qgl.scene.state.Color((1.0,1.0,1.0,1.0))
        else: self.color_mouse = qgl.scene.state.Color((1.0,1.0,1.0,0.0))
        
        img = os.path.join(config_data.theme, 'selector.png')
        tex = qgl.scene.state.Texture(img)
        quad = qgl.scene.state.Quad((45,4.5))
        self._w_select = qgl.scene.Group()
        self._w_select.add(tex, self.color, quad)
        self._w_select.translate = (11.0,-2.0,-60.0)
        viewport.add(self._w_select)
        
        img = os.path.join(config_data.theme, 'arrow-up.png')
        tex = qgl.scene.state.Texture(img)
        quad = qgl.scene.state.Quad((2,2))
        self._w_up = qgl.scene.Group()
        self._w_up.add(tex, self.color_mouse, quad)
        self._w_up.translate = (3.0,14,-50.0)
        self._w_up.selectable = True
        viewport.add(self._w_up)
        
        img = os.path.join(config_data.theme, 'arrow-down.png')
        tex = qgl.scene.state.Texture(img)
        quad = qgl.scene.state.Quad((2,2))
        self._w_down = qgl.scene.Group()
        self._w_down.add(tex, self.color_mouse, quad)
        self._w_down.translate = (3.0,-18,-50.0)
        self._w_down.selectable = True
        viewport.add(self._w_down)
        
        img = os.path.join(config_data.theme, 'arrow-left.png')
        tex = qgl.scene.state.Texture(img)
        quad = qgl.scene.state.Quad((2,2))
        self._w_left = qgl.scene.Group()
        self._w_left.add(tex, self.color_mouse, quad)
        self._w_left.translate = (-8.0,-1.9,-50.0)
        self._w_left.selectable = True
        viewport.add(self._w_left)
        
        img = os.path.join(config_data.theme, 'arrow-right.png')
        tex = qgl.scene.state.Texture(img)
        quad = qgl.scene.state.Quad((2,2))
        self._w_right = qgl.scene.Group()
        self._w_right.add(tex, self.color_mouse, quad)
        self._w_right.translate = (26.0,-1.9,-55.0)
        self._w_right.selectable = True
        viewport.add(self._w_right)
        
        self._w_tracks = {}
        k = 0
        for track in self.tracks:
            try:
                if str(track.title) == 'None' or str(track.title) == "" or str(track.title) == "Unknown":
                    text = qgl.scene.state.Text("Unknown track", config_data.fonts + "/URWGothicL.ttf", (0.8, 0.8, 0.8), None, 24)
                elif len(str(track.title)) > 26:
                    text = qgl.scene.state.Text(str(track.title)[:26] + "...", config_data.fonts + "/URWGothicL.ttf", (0.8, 0.8, 0.8), None, 24)
                else:
                    text = qgl.scene.state.Text(str(track.title), config_data.fonts + "/URWGothicL.ttf", (0.8, 0.8, 0.8), None, 24)
            except:
                text = qgl.scene.state.Text("Unknown track", config_data.fonts + "/URWGothicL.ttf", (0.8, 0.8, 0.8), None, 24)
            self._w_tracks[k] = qgl.scene.Group()
            self._w_tracks[k].add(text, self.color)
            self._w_tracks[k].translate = (-3.0,4.34-(1.92*(k+3)),-23.0)
            if k < 4: viewport.add(self._w_tracks[k])
            k+=1
            
        actions.Fade(self.color, alpha=1.0, time=3.0)
        
    def scroll(self):
        for k in xrange(len(self.tracks)):
            try:
                viewport.remove(self._w_tracks[k])
            except: pass
            if k - self.pos < 4 and k - self.pos > -4:
                viewport.add(self._w_tracks[k])
            self._w_tracks[k].translate = (-3.0,4.34-(1.92*(k+3-self.pos)),-23.0)
               
    def goto_artists(self):
        data.album_pos = 0
        eventhandler.clear()
        self.parent.destroy()
        import artists
        artists.MusicArtists()
        root_node.accept(compiler) 
        
    def goto_playing(self):
        data.artist_pos = self.pos
        eventhandler.clear()
        self.parent.destroy()
        import playing
        data.audio = self.tracks[self.pos]
        data.playlist.clear()
        for item in self.tracks:
            data.playlist.add(item)
        playing.MusicPlaying()
        root_node.accept(compiler)
                         
    def handle_events(self, events):
        if config.input == "keyboard + mouse":
            for event in events:
                if event.type is KEYUP:
                    if event.key == K_DOWN:
                        if self.pos + 1 < len(self.tracks): 
                            self.pos+=1
                            self.scroll()
                    if event.key == K_UP:
                        if self.pos > 0:
                            self.pos-=1
                            self.scroll()  
                    if event.key == K_LEFT:
                        self.goto_artists() 
                    if event.key == K_RIGHT:
                        self.goto_playing()
                elif event.type == MOUSEBUTTONDOWN and mousehandler.active():
                    picker.set_position(event.pos)
                    root_node.accept(compiler)
                    root_node.accept(picker)          
                    if self._w_up in picker.hits:
                        if self.pos > 0:
                            self.pos-=1
                            self.scroll()                        
                    if self._w_down in picker.hits:
                        if self.pos + 1 < len(self.tracks): 
                            self.pos+=1
                            self.scroll() 
                    if self._w_left in picker.hits:
                        self.goto_artists()
                    if self._w_right in picker.hits:
                        self.goto_playing()
                elif event.type == 'mouse_active':
                    self.mouse_active = True
                    actions.Fade(self.color_mouse, alpha=1.0, time=.5)        
                elif event.type == 'mouse_inactive':
                    self.mouse_active = False
                    actions.Fade(self.color_mouse, alpha=0.0, time=.5)    
                        
    def destroy(self):
        eventhandler.unsubscribe(self)
        viewport.remove(self._w_select)
        viewport.remove(self._w_up)
        viewport.remove(self._w_down)
        viewport.remove(self._w_left)
        viewport.remove(self._w_right)
        for w in self._w_tracks:
            try:
                viewport.remove(self._w_tracks[w])
            except: pass
    
class AlbumArtView(object):
    def __init__(self, album):
        self.album = album
        for item in data.audio_library:
            if item.album == self.album:
                self.album = item
        self.draw()
    def draw(self):
        
        # the shared color for the album art and its reflex
        self.color = qgl.scene.state.Color((1.0,1.0,1.0,0.0))
        self.color_reflex = qgl.scene.state.Color((1.0,1.0,1.0,0.0))
        # the album art
        img = self.album.album_art
        if img != '':
            tex = qgl.scene.state.Texture(img)
            quad = qgl.scene.state.Quad((14,14))
            self._w_album_art = qgl.scene.Group()
            self._w_album_art.add(tex, self.color, quad)
            self._w_album_art.translate = (-19.5,4,-45)
            viewport.add(self._w_album_art)
            self._w_album_art.axis = (0.0,1.0,0.0)
            #self.Walbumart.angle = 30    
        else: 
            img = os.path.join(config_data.theme, 'music-unknown-album.png')
            tex = qgl.scene.state.Texture(img)
            quad = qgl.scene.state.Quad((14,14))
            self._w_album_art = qgl.scene.Group()
            self._w_album_art.add(tex, self.color, quad)
            self._w_album_art.translate = (-19.5,4,-45)
            viewport.add(self._w_album_art)

        print 'img is: ' + str(img)
        img = visuals.reflex(img, intensity=25)
        tex = qgl.scene.state.Texture(img)
        quad = qgl.scene.state.Quad((14,14))
        self._w_album_art_reflex = qgl.scene.Group()
        self._w_album_art_reflex.add(tex, self.color_reflex, quad)
        self._w_album_art_reflex.translate = (-19.5,-10,-45)
        viewport.add(self._w_album_art_reflex)
        actions.Fade(self.color, alpha=1.0, time=3.0)
        actions.Fade(self.color_reflex, alpha=.5, time=3.0)

    def destroy(self):
        viewport.remove(self._w_album_art)
        viewport.remove(self._w_album_art_reflex)
            
class AlbumArtBackgroundView(object):
    def __init__(self):
        eventhandler.subscribe(self)
        self._w_album_art = {}
        self.slide_direction = 'down'
        self.slide_time = 0.0
        for album in data.albums:
            if data.albums[album][1] != '': self.slide_time+=3.0
        self.draw()
        
    def draw(self):
        self.color = qgl.scene.state.Color((1.0,1.0,1.0,0.0))
        k = 0
        for album in data.albums:
            if data.albums[album][1] != '': # only albums with album art
                img = data.albums[album][1]
                tex = qgl.scene.state.Texture(img)
                quad = qgl.scene.state.Quad((14,14))
                self._w_album_art[k] = qgl.scene.Group()
                self._w_album_art[k].add(tex, self.color, quad)
                self._w_album_art[k].translate = (-23,-16.6+15*k,-55)
                viewport.add(self._w_album_art[k])
                self._w_album_art[k].axis = (0.0,1.0,0.0)
                self._w_album_art[k].angle = 30
                k+=1  
        for k in xrange(len(self._w_album_art)):
            y = (-23,13.4-((len(self._w_album_art)-1-k)*15),-55)
            actions.Move(self._w_album_art[k], y, self.slide_time)               

        actions.Fade(self.color, alpha=0.5, time=3.0)
        self._a_slidetimer = actions.Timer(time=self.slide_time)
        
    def handle_events(self, events):
        for event in events:
            if event.type == "action_finished":
                if event.key == self._a_slidetimer:
                    if self.slide_direction == 'down':
                        self.slide_direction = 'up'
                        for k in xrange(len(self._w_album_art)):
                            y = (-23,-16.6+15*k,-55)
                            actions.Move(self._w_album_art[k], y, self.slide_time)  
                    else: 
                        self.slide_direction = 'down'
                        for k in xrange(len(self._w_album_art)):
                            y = (-23,13.4-((len(self._w_album_art)-1-k)*15),-55)
                            actions.Move(self._w_album_art[k], y, self.slide_time)   
                    self._a_slidetimer = actions.Timer(time=self.slide_time)                  
                
    def destroy(self):
        eventhandler.unsubscribe(self)
        for k in xrange(len(self._w_album_art)):
            viewport.remove(self._w_album_art[k])
        self._a_slidetimer.stop()
        
class AlbumInfo(object):
    def __init__(self, album):
        self.album = album
        for item in data.audio_library:
            if item.album == self.album:
                self.album = item
        self.draw()
    def draw(self):
        if str(self.album.album) == 'None' or str(self.album.album) == "" or str(self.album.album) == "Unknown":
            text = qgl.scene.state.Text("Unknown album", config_data.fonts + "/URWGothicL.ttf", (0.8, 0.8, 0.8), None, 34)
        else: text = qgl.scene.state.Text(str(self.album.album), config_data.fonts + "/URWGothicL.ttf", (0.8, 0.8, 0.8), None, 34)
        self._w_album = qgl.scene.Group()
        self._w_album.add(text)
        self._w_album.translate = (-20.2,-5,-35)
        viewport.add(self._w_album)
        
        if str(self.album.artist) == 'None' or str(self.album.artist) == "" or str(self.album.artist) == "Unknown":
            text = qgl.scene.state.Text("Unknown artist", config_data.fonts + "/URWGothicL.ttf", (0.8, 0.8, 0.8), None, 28)
        else: text = qgl.scene.state.Text(str(self.album.artist), config_data.fonts + "/URWGothicL.ttf", (0.8, 0.8, 0.8), None, 28)
        self._w_artist = qgl.scene.Group()
        self._w_artist.add(text)
        self._w_artist.translate = (-20.12,-7,-35)
        viewport.add(self._w_artist) 
                
        if str(self.album.year) == 'None' or str(self.album.year) == "" or str(self.album.year) == "Unknown":
            text = qgl.scene.state.Text("Unknown year", config_data.fonts + "/URWGothicL.ttf", (0.8, 0.8, 0.8), None, 26)
        else: text = qgl.scene.state.Text(str(self.album.year), config_data.fonts + "/URWGothicL.ttf", (0.8, 0.8, 0.8), None, 26)
        self._w_year = qgl.scene.Group()
        self._w_year.add(text)
        self._w_year.translate = (-20,-9,-35)
        viewport.add(self._w_year)
    def destroy(self):
        viewport.remove(self._w_album)
        viewport.remove(self._w_artist)
        viewport.remove(self._w_year)